/* Copyright (C) 2011 clueless <clueless.mmopeon@gmail.com>
 *
 * This file is part of MMO Peon.
 *
 * MMO Peon is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MMO Peon is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MMO Peon.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "waypoints.h"
#include "objectmap.h"

Waypoints::Waypoints(const std::string& filename)
{
    init = false;
    LoadWaypoints(filename);
}

void Waypoints::LoadWaypoints(const std::string& filename)
{
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file(filename.c_str());
    if (!result)
        return;

    auto wps = doc.child("Waypoints");
    for (pugi::xml_node coord = wps.child("Waypoint"); coord; coord = coord.next_sibling("Waypoint"))
    {
        RomCoords wpCoords;
        wpCoords.x = coord.attribute("X").as_float();
        wpCoords.y = coord.attribute("Y").as_float();
        wpCoords.z = coord.attribute("Z").as_float();
        data.push_back(wpCoords);
    }
}

bool Waypoints::IsInit() const
{
    return init;
}

bool Waypoints::IsEmpty() const
{
    return data.empty();
}

const RomCoords& Waypoints::Current() const
{
    return *current;
}

const RomCoords& Waypoints::Next()
{
    current++;
    if (current == data.end())
        current = data.begin();

    return *current;
}

const RomCoords& Waypoints::Previous()
{
    if (current == data.begin())
        current = data.end();
    current--;

    return *current;
}

const RomCoords& Waypoints::Nearest(const RomCoords& source)
{
    std::vector<RomCoords>::iterator nearest;
    float distance = -1.0;
    for (auto it = data.begin(); it != data.end(); it++)
    {
        float newDistance = it->Distance(source);
        if (distance < 0 || newDistance < distance)
        {
            distance = newDistance;
            nearest = it;
        }
    }
    init = true;
    current = nearest;
    return *nearest;
}
